package com.heima.comment.service.impl;


import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.heima.apis.user.IUserClient;
import com.heima.comment.pojos.ApComment;
import com.heima.comment.pojos.ApCommentRepay;
import com.heima.comment.pojos.ApCommentRepayLike;
import com.heima.comment.service.CommentRepayService;
import com.heima.comment.service.CommentService;
import com.heima.common.constants.CommentConstants;
import com.heima.common.redis.CacheService;
import com.heima.model.comment.dtos.CommentRepayDto;
import com.heima.model.comment.dtos.CommentRepayLikeDto;
import com.heima.model.comment.dtos.CommentRepaySaveDto;
import com.heima.model.comment.vos.ApCommentRepayVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.user.pojos.ApUser;
import com.heima.utils.thread.ApThreadLocalUtils;
import com.mongodb.client.result.DeleteResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author yht
 * @date 2022/1/23 16:03
 */
@Service
@Slf4j
@Transactional
public class CommentRepayServiceImpl implements CommentRepayService {
    @Autowired
    private IUserClient iUserClient;
    @Autowired
    private MongoTemplate mongoTemplate;
    @Autowired
    private CacheService cacheService;
    @Autowired
    private CommentService commentService;

    /**
     * 保存评论回复的信息
     * @param dto
     * @return
     */
    @Override
    public ResponseResult saveComment(CommentRepaySaveDto dto) {
        if(ObjectUtil.isEmpty(dto)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        ApUser user = ApThreadLocalUtils.getUser();
        if(user==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //根据id远程调用查询用户信息
        ResponseResult userById = iUserClient.findUserById(Long.parseLong(String.valueOf(user.getId())));
        if(userById.getCode()!=200){
            return ResponseResult.errorResult(AppHttpCodeEnum.SERVER_ERROR,"远程调用user模块出错:"+userById.getErrorMessage());
        }
        ApUser apUser = JSON.parseObject(String.valueOf(userById.getData()), ApUser.class);
        //存入mongo数据库
        ApCommentRepay commentRepay=new ApCommentRepay();
        commentRepay.setAuthorId(apUser.getId());
        commentRepay.setAuthorName(apUser.getName());
        commentRepay.setCommentId(String.valueOf(dto.getCommentId()));
        commentRepay.setContent(dto.getContent());
        commentRepay.setCreatedTime(new Date());
        commentRepay.setUpdatedTime(new Date());
        commentRepay.setLikes(0);
        ApCommentRepay apCommentRepay = mongoTemplate.save(commentRepay);
        //保存回复点赞数到reids中
        cacheService.hPut(CommentConstants.COMMENT_REPLY_REDISKEY+apCommentRepay.getId(),
                CommentConstants.REPLY_USER+apUser.getId(),String.valueOf(0));
        //更新comment表中的评论数
        ApComment apComment = commentService.findCommentById(dto.getCommentId().toString());
        Integer countReply=apComment.getReply()+1;
        apComment.setReply(countReply);
        mongoTemplate.save(apComment);
        //更新redis中的回复数
        cacheService.hPut(CommentConstants.COMMENT_LIKE_REDISKEY+dto.getCommentId(),
                CommentConstants.COMMENT_REPLY_COUNT,countReply.toString());

        return ResponseResult.okResult(apComment);
    }

    /**
     * 回复点赞
     * @param dto
     * @return
     */
    @Override
    public ResponseResult commentLike(CommentRepayLikeDto dto) {

        if(ObjectUtil.isEmpty(dto)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        ApUser user = ApThreadLocalUtils.getUser();
        if(user==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }

        if(dto.getOperation()==0){
            //点赞
            boolean like = isLike(CommentConstants.COMMENT_REPLY_REDISKEY + dto.getCommentRepayId(),
                    CommentConstants.REPLY_USER + user.getId());
            if(like){
               return ResponseResult.okResult(cacheService.hGet(CommentConstants.COMMENT_REPLY_REDISKEY+dto.getCommentRepayId(),
                       CommentConstants.COMMENT_REPLY_COUNT));
            }

            //1.把回复点赞的操作保存到mongo中
            ApCommentRepayLike commentRepayLike=new ApCommentRepayLike();
            commentRepayLike.setCommentRepayId(dto.getCommentRepayId());
            commentRepayLike.setAuthorId(user.getId());
            mongoTemplate.save(commentRepayLike);
            //2.更新回复的数量
            ApCommentRepay commentRepay = mongoTemplate.findById(dto.getCommentRepayId(), ApCommentRepay.class);
            Integer count=commentRepay.getLikes()+1;
            commentRepay.setLikes(count);
            mongoTemplate.save(commentRepay);
            //3.更新redis中的数量，更新回复点赞的用户状态
            cacheService.hPut(CommentConstants.COMMENT_REPLY_REDISKEY+dto.getCommentRepayId(),
                    CommentConstants.COMMENT_REPLY_COUNT,String.valueOf(count));
            cacheService.hPut(CommentConstants.COMMENT_REPLY_REDISKEY+dto.getCommentRepayId(),
                    CommentConstants.REPLY_USER+user.getId(),String.valueOf(0));
            return ResponseResult.okResult(count);
        }else if(dto.getOperation()==1){
            //取消点赞
            boolean like = isLike(CommentConstants.COMMENT_REPLY_REDISKEY + dto.getCommentRepayId(),
                    CommentConstants.REPLY_USER + user.getId());
            if(!like){
                return ResponseResult.okResult(cacheService.hGet(CommentConstants.COMMENT_REPLY_REDISKEY+dto.getCommentRepayId(),
                        CommentConstants.COMMENT_REPLY_COUNT));
            }
            //删除数据库点赞状态
            Query query=new Query(Criteria.where("commentRepayId").in(dto.getCommentRepayId())
                    .and("authorId").is(user.getId()));
            DeleteResult remove = mongoTemplate.remove(query, ApCommentRepayLike.class);
            remove.getDeletedCount();
            //修改数据点赞数
            ApCommentRepay commentRepay = mongoTemplate.findById(dto.getCommentRepayId(), ApCommentRepay.class);
            Integer count=commentRepay.getLikes()-1;
            commentRepay.setLikes(count);
            mongoTemplate.save(commentRepay);
            //3.更新redis中的数量，更新回复点赞的用户状态
            cacheService.hPut(CommentConstants.COMMENT_REPLY_REDISKEY+dto.getCommentRepayId(),
                    CommentConstants.COMMENT_REPLY_COUNT,String.valueOf(count));
            cacheService.hDelete(CommentConstants.COMMENT_REPLY_REDISKEY+dto.getCommentRepayId(),
                    CommentConstants.REPLY_USER+user.getId());
            return ResponseResult.okResult(count);
        }else {
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID);
        }

    }

    /**
     * 查询评论表回复列表
     * @return
     */
    @Override
    public ResponseResult findCommentRepay(CommentRepayDto dto) {
        if(ObjectUtil.isEmpty(dto)){
            return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_REQUIRE);
        }
        ApUser user = ApThreadLocalUtils.getUser();
        if(user==null){
            return ResponseResult.errorResult(AppHttpCodeEnum.NEED_LOGIN);
        }
        //根据id查询回复列表
        if(dto.getSize()==null || dto.getSize()==0){
            dto.setSize(10);
        }if(dto.getSize()>20){
            dto.setSize(20);
        }
        if(dto.getMinDate()==null){
            dto.setMinDate(new Date());
        }
        //查询评论列表
        Query query=new Query(Criteria.where("commentId").is(dto.getCommentId())
                .and("createdTime").lt(dto.getMinDate()))
                .with(Sort.by(Sort.Order.desc("createdTime"))).limit(dto.getSize());
        List<ApCommentRepay> apCommentRepays = mongoTemplate.find(query, ApCommentRepay.class);
        //创建返回的结果list对象
        List<ApCommentRepayVo> commentRepayVos=new ArrayList<>();
        //判断当前用户是否点赞
        for (ApCommentRepay apCommentRepay : apCommentRepays) {
            //创建返回的vo对象
            ApCommentRepayVo commentRepayVo=new ApCommentRepayVo();
            //拷贝对象
            BeanUtil.copyProperties(apCommentRepay,commentRepayVo);
            //判断当前用户对回复是否点赞
            boolean like = isLike(CommentConstants.COMMENT_REPLY_REDISKEY + apCommentRepay.getId(),
                    CommentConstants.REPLY_USER + user.getId());
            //设置是否点赞的标识
            if(like){
                commentRepayVo.setOperation(null);
            }else {
                commentRepayVo.setOperation(0);
            }
            //添加集合
            commentRepayVos.add(commentRepayVo);
        }
        return ResponseResult.okResult(commentRepayVos);
    }

    /**
     * 查询redis中是否有
     * @param redisKey
     * @param hashKey
     * @return
     */
    public boolean isLike(String redisKey,String hashKey){
        return cacheService.hExists(redisKey,hashKey);
    }
}
